﻿// ----------------------------------------------------------------------------------
// Microsoft Developer & Platform Evangelism
// 
// Copyright (c) Microsoft Corporation. All rights reserved.
// 
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// ----------------------------------------------------------------------------------
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
// ----------------------------------------------------------------------------------

namespace umbraco.ACSExtensions
{
    using System;
    using System.Configuration;
    using System.Globalization;
    using System.IO;
    using System.Linq;
    using System.Net.Mail;
    using System.Net.Sockets;
    using System.Text;
    using System.Web;
    using Microsoft.IdentityModel.Claims;
    using umbraco.cms.businesslogic.member;
    using umbraco.IO;

    public static class ACSExtensionsSettings
    {
        // Social Member type
        internal const string SocialMemberTypeAlias = "socialMember";

        internal const string SocialMemberTypeText = "Social Member";

        // Claim Types
        internal const string IdentityProviderClaimType = "http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider";
        
        internal const string OrganizationClaimType = "http://schemas.umbraco.com/claims/2009/08/organization";

        // Login Macros
        internal const string FederatedLoginMacroAlias = "acsExtensions.federatedLoginMacro";

        internal const string LoginMacroAlias = "acsExtensions.loginMacro";

        // Notifications
        internal const string ActivationPageParameters = "?ticketNumber={0}";

        // Generic Properties
        public const string MemberIdentityProviderPropertyAlias = "identityProvider";

        public const string MemberIdentityProviderPropertyName = "Identity Provider";

        public const string MemberIsActivatedPropertyAlias = "isActivated";

        public const string MemberIsActivatedPropertyName = "Is Activated";

        public const string MemberInvitationSentPropertyAlias = "invitationSent";

        public const string MemberInvitationSentPropertyName = "Invitation Sent";

        public const string TemporaryMemberPrefix = "temp_0BCCAF5E-EF68-4F11-9652-D4F642453ABD_";

        public static bool IsTemporaryMember(string loginName)
        {
            return loginName.StartsWith(TemporaryMemberPrefix, StringComparison.OrdinalIgnoreCase);
        }

        public static bool IsSignInFromBusinessIdentityProvider(IClaimsIdentity identity)
        {
            var mappingRuleService = new MappingRuleService();
            var businessIdentityProviders = mappingRuleService.RetrieveBusinessIdentityProviders();
            
            return
                identity.IsAuthenticated &&
                identity.Claims.Any(c => c.ClaimType == ACSExtensionsSettings.IdentityProviderClaimType) &&
                businessIdentityProviders.Any(ip => ip.Id.Equals(identity.Claims.Single(c => c.ClaimType == ACSExtensionsSettings.IdentityProviderClaimType).Value, StringComparison.OrdinalIgnoreCase));
        }

        public static bool EnabledProgrammaticAccessToAcs
        {
            get
            {
                return
                    !string.IsNullOrEmpty(ConfigurationManager.AppSettings["AcsNamespace"]) &&
                    !string.IsNullOrEmpty(ConfigurationManager.AppSettings["AcsManagementKey"]);
            }
        }

        public static string IdentityProvidersMappingRulesPath
        {
            get 
            {
                return SystemDirectories.Data + "/IdentityProvidersMappingRules.xml";
            }
        }

        public static MemberType SocialMemberType
        {
            get
            {
                return MemberType.GetByAlias(ACSExtensionsSettings.SocialMemberTypeAlias);
            }
        }

        public static string GenerateActivationUrl(Guid ticketNumber)
        {
            return ActivationPage + string.Format(CultureInfo.InvariantCulture, ActivationPageParameters, ticketNumber);
        }

        public static string ActivationPage
        {
            get
            {
                var defaultValue = "~/activation";
                var activationPage = string.Empty;

                try
                {
                    activationPage = ConfigurationManager.AppSettings["ActivationPage"] ?? defaultValue;
                }
                catch (ConfigurationErrorsException)
                {
                    activationPage = defaultValue;
                }

                return VirtualPathUtility.ToAbsolute(activationPage);
            }
        }

        public static string ActivationSenderAddress
        {
            get
            {
                var defaultValue = "no-reply@domain.com";

                try
                {
                    return ConfigurationManager.AppSettings["ActivationSenderAddress"] ?? defaultValue;
                }
                catch (ConfigurationErrorsException)
                {
                    return defaultValue;
                }
            }
        }

        public static string ActivationSenderName
        {
            get
            {
                var defaultValue = string.Empty;

                try
                {
                    return ConfigurationManager.AppSettings["ActivationSenderName"] ?? defaultValue;
                }
                catch (ConfigurationErrorsException)
                {
                    return defaultValue;
                }
            }
        }

        public static string ActivationEmailSubject
        {
            get
            {
                var defaultValue = "Please Activate your Account";

                try
                {
                    return ConfigurationManager.AppSettings["ActivationEmailSubject"] ?? defaultValue;
                }
                catch (ConfigurationErrorsException)
                {
                    return defaultValue;
                }
            }
        }

        public static string ActivationEmailTemplateBody
        {
            get
            {
                var notificationTemplatePath = IOHelper.MapPath(ACSExtensionsSettings.ActivationEmailTemplatePath, false);
                var notificationTemplateText = File.ReadAllText(notificationTemplatePath);
                var bodyInitial = "<div id=\"activationMessage\">";
                var bodyFinal = "</div>";
                return notificationTemplateText.Substring(
                    notificationTemplateText.IndexOf(bodyInitial, StringComparison.OrdinalIgnoreCase) + bodyInitial.Length,
                    notificationTemplateText.LastIndexOf(bodyFinal, StringComparison.OrdinalIgnoreCase) - notificationTemplateText.IndexOf(bodyInitial, StringComparison.OrdinalIgnoreCase) - bodyInitial.Length).Trim();
            }
        }

        public static string ActivationEmailTemplatePath
        {
            get
            {
                var defaultValue = "~/App_Data/ActivationEmailTemplate.htm";
                
                try
                {
                    return ConfigurationManager.AppSettings["ActivationEmailTemplate"] ?? defaultValue;
                }
                catch (ConfigurationErrorsException)
                {
                    return defaultValue;
                }
            }
        }

        public static bool ValidSmtp()
        {
            bool valid = false;
            var smtpClient = new SmtpClient();
            var tcpClient = new TcpClient();

            try
            {
                tcpClient.Connect(smtpClient.Host, smtpClient.Port);

                if (tcpClient.Connected)
                {
                    NetworkStream networkStream = tcpClient.GetStream();
                    var streamReader = new StreamReader(networkStream);

                    valid = streamReader.ReadLine().Contains("220");
                    tcpClient.Close();
                }
            }
            catch
            {
            }

            return valid;
        }

        internal static string GetAppDomainAddress()
        {
            var request = HttpContext.Current.Request;
            var reqUrl = request.Url;
            var domainUrl = new StringBuilder();

            // Force https
            domainUrl.Append(Uri.UriSchemeHttps);
            domainUrl.Append("://");
            domainUrl.Append(request.Headers["Host"] ?? reqUrl.Authority);

            return domainUrl.ToString();
        }
    }
}